package com.gitee.feizns.explore.data_structure.queue;

import java.util.function.Consumer;

/**
 * @author feizns
 * @since 2019/10/8
 */
public class ArrayQueue<T> implements Queue<T> {

    private int size;

    private int head;

    private int tail;

    private Object[] ary;

    public ArrayQueue(int capacity) {
        ary = new Object[capacity];
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public boolean enqueue(T o) {
        if ( isFull() )
            return false;

        ary[tail] = o;
        tail = nextIndex(tail);
        size++;
        return true;
    }

    @Override
    public T dequeue() {
        if ( isEmpty() )
            return null;

        T ret = (T) ary[head];
        head = nextIndex(head);
        size--;
        return ret;
    }

    @Override
    public T peek() {
        return isEmpty() ? null : (T) ary[head];
    }

    @Override
    public boolean isFull() {
        return size == ary.length;
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public void forEach(Consumer<T> t) {
        for (int i = 0, s = head; i < size; i++, s = nextIndex(s)) {
            t.accept((T) ary[s]);
        }
    }

    private int nextIndex(int i) {
        return i == ary.length - 1 ? 0 : i + 1;
    }

}
